﻿using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MKAdminCore.SignalR
{
    public class HubMain : Hub
    {
        public static ConcurrentDictionary<string, UserChatIdentifyMainInfo> UserConnectionList = new ConcurrentDictionary<string, UserChatIdentifyMainInfo>();

        /// <summary>
        /// 建立连接
        /// </summary>
        /// <returns></returns>
        public override Task OnConnectedAsync()
        {
            //每次都会产生新的ConnectionId
            string connectionId = Context.ConnectionId;
            var userInfo = new UserChatIdentifyMainInfo()
            {
                ConnectionId = connectionId,
                HeadUrl = $"/images/userHead/{(new Random()).Next(1, 100).ToString()}.jpg",
                NickName = (new Random()).Next(1000, 9999).ToString()
            };
            UserConnectionList.TryAdd(connectionId, userInfo);

            var otherUserConnections = UserConnectionList.Where(q => q.Key != connectionId).Select(q => q.Key).ToList();
            //通知其他用户有新用户上线
            if (otherUserConnections != null && otherUserConnections.Count > 0)
            {
                Clients.Clients(otherUserConnections).SendAsync("noticeClientOnLine", userInfo);
            }

            //通知自己所有客户端信息
            var otherClients = UserConnectionList.Where(q => q.Key != connectionId).Select(q => q.Value).ToList();
            Clients.Client(connectionId).SendAsync("loadClientAll", otherClients, userInfo);
            return base.OnConnectedAsync();
        }

        /// <summary>
        /// 离线
        /// </summary>
        /// <param name="exception"></param>
        /// <returns></returns>
        public override Task OnDisconnectedAsync(Exception exception)
        {
            string connectionId = Context.ConnectionId;
            var userChatIdentifyMainInfo = new UserChatIdentifyMainInfo();
            //移除客户端链接
            UserConnectionList.TryRemove(connectionId, out userChatIdentifyMainInfo);

            List<string> connectionIds = UserConnectionList.Select(q => q.Key).ToList();

            if (connectionIds != null && connectionIds.Count > 0)
            {
                Clients.Clients(connectionIds).SendAsync("noticeClientOnDisconnected", connectionId);
            }
            return base.OnDisconnectedAsync(exception);
        }

        public void SendMessage(ChatMsgParamMainInfo content)
        {
            try
            {
                sendMsgToClient(content);
            }
            catch (Exception ex)
            {
                StringBuilder itemS = new StringBuilder();
                itemS.AppendLine("发送消息异常:" + ex.Message);
                //LogHelper.Error(itemS.ToString());
            }
        }

        /// <summary>
        /// 发送消息给用户
        /// </summary>
        private void sendMsgToClient(ChatMsgParamMainInfo content)
        {
            string senderConnectionId = Context.ConnectionId;

            var msgResponse = new SendMessageResponse();

            var recevierInfo = UserConnectionList.Where(q => q.Key == content.ReceiverConnectionId);
            if (!recevierInfo.Any())
            {
                //对方不存在或离线 通知发送者
                msgResponse.senderConnectionId = content.ReceiverConnectionId;
                msgResponse.msgType = 10;
                msgResponse.text = "对方不存在或离线";

                Clients.Client(senderConnectionId).SendAsync("acceptMsgFromClient", msgResponse);
                return;
            }

            string senderNickName = "";
            string senderHeadUrl = "";
            var senderInfo = UserConnectionList.Where(q => q.Key == Context.ConnectionId);
            if (senderInfo.Any())
            {
                senderNickName = senderInfo.FirstOrDefault().Value.NickName;
                senderHeadUrl = senderInfo.FirstOrDefault().Value.HeadUrl;

                msgResponse.senderConnectionId = senderConnectionId;
                msgResponse.senderNickName = senderNickName;
                msgResponse.senderHeadUrl = senderHeadUrl;
                msgResponse.msgType = content.MsgType;
                msgResponse.text = content.Text;
                msgResponse.imgUrl = content.ImgUrl;
                msgResponse.sendTime = DateTime.Now;

                Clients.Client(content.ReceiverConnectionId).SendAsync("acceptMsgFromClient", msgResponse);
                //todo:这里可以通知发送者 发送成功

            }
            else
            {
                //服务连接失败,请稍后重试 通知发送者
                msgResponse.senderConnectionId = content.ReceiverConnectionId;
                msgResponse.msgType = 10;
                msgResponse.text = "服务连接失败,请稍后重试";

                Clients.Client(senderConnectionId).SendAsync("acceptMsgFromClient", msgResponse);
                return;
            }

        }
    }

    /// <summary>
    /// 建立链接实体对象
    /// </summary>
    public class UserChatIdentifyMainInfo
    {
        /// <summary>
        /// 客户端推送消息链接Id
        /// </summary>
        public string ConnectionId { get; set; }
        /// <summary>
        /// 聊天昵称
        /// </summary>
        public string NickName { get; set; }
        /// <summary>
        /// 聊天头像
        /// </summary>
        public string HeadUrl { get; set; }
    }

    /// <summary>
    /// 聊天实体对象
    /// </summary>
    public class ChatMsgParamMainInfo
    {
        /// <summary>
        /// 接收者对象客户端Id(用来推送消息)
        /// </summary>
        public string ReceiverConnectionId { get; set; }
        /// <summary>
        /// 消息类型（0:文字 1:图片  10:系统消息） 
        /// </summary>
        public int MsgType { get; set; }
        /// <summary>
        /// 文字内容
        /// </summary>
        public string Text { get; set; }
        /// <summary>
        /// 图片Url
        /// </summary>
        public string ImgUrl { get; set; }
    }

    /// <summary>
    /// 发送消息参数
    /// </summary>
    public class SendMessageParam
    {
        /// <summary>
        /// 接收者对象客户端Id(用来推送消息)
        /// </summary>
        public string ReceiverConnectionId { get; set; }
        /// <summary>
        /// 消息类型（0:文字 1:图片）
        /// </summary>
        public int MsgType { get; set; }
        /// <summary>
        /// 文字内容
        /// </summary>
        public string Text { get; set; }
        /// <summary>
        /// 图片Url
        /// </summary>
        public string ImgUrl { get; set; }
    }

    /// <summary>
    /// 发送消息响应参数
    /// </summary>
    public class SendMessageResponse
    {
        /// <summary>
        /// 发送人连接id
        /// </summary>
        public string senderConnectionId { get; set; }
        /// <summary>
        /// 发送人昵称
        /// </summary>
        public string senderNickName { get; set; }
        /// <summary>
        /// 发送人头像
        /// </summary>
        public string senderHeadUrl { get; set; }
        /// <summary>
        /// 消息类型 0：文字  1：图片   10：系统消息
        /// </summary>
        public int msgType { get; set; }
        /// <summary>
        /// 文字内容
        /// </summary>
        public string text { get; set; }
        /// <summary>
        /// 图片
        /// </summary>
        public string imgUrl { get; set; }
        /// <summary>
        /// 发送时间
        /// </summary>
        public DateTime sendTime { get; set; } = DateTime.Now;
    }
}
